package com.xm.redis;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

public class RedisDistributedLock {
    private final StringRedisTemplate redisTemplateCas;
    private final String lockKey;
    private final String lockValue;
    private final long expireTime;

    // 构造函数属性赋值
    public RedisDistributedLock(StringRedisTemplate redisTemplate, String lockKey, long expireTime) {
        this.redisTemplateCas = redisTemplate;
        this.lockKey = lockKey;
        this.lockValue = UUID.randomUUID().toString();
        this.expireTime = expireTime;
    }

    /**
     * 尝试获取锁
     */
    public boolean tryLock() {
        Boolean success = redisTemplateCas.opsForValue().setIfAbsent(lockKey, lockValue, expireTime, TimeUnit.MILLISECONDS);
        return Boolean.TRUE.equals(success);
    }

    /**
     * 释放锁（Lua 脚本保证原子性）
     */
    public void unlock() {
//        使用 redis.call('get') 查询锁键当前值。对比查询结果与传入的唯一标识符。若匹配，执行 redis.call('del') 删除锁键；否则返回 0。
        String luaScript =
            "if redis.call('get', KEYS[1]) == ARGV[1] then " +
            "   return redis.call('del', KEYS[1]) " +
            "else " +
            "   return 0 " +
            "end";

        DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>(luaScript, Long.class);
        redisTemplateCas.execute(redisScript, Collections.singletonList(lockKey), lockValue);
    }
}
